package graph

import (
	"fmt"

	"github.com/goccy/go-graphviz"
	"github.com/goccy/go-graphviz/cgraph"
)

// 节点有向连接
type diLine struct {
	from *cgraph.Node
	to   *cgraph.Node
}

// OutputSVG 输出图的SVG文件
func (g *Digraph) OutputSVG(filename string) error {
	gviz := graphviz.New()
	graph, err := gviz.Graph()
	if err != nil {
		return err
	}

	defer func() error {
		if err := graph.Close(); err != nil {
			return err
		}
		return gviz.Close()
	}()

	// 创建节点
	nodes := make(map[string]*cgraph.Node)
	for _, v := range g.Vertexes {
		node, err := graph.CreateNode(v.GetName())
		if err != nil {
			return err
		}

		nodes[v.GetName()] = node
	}

	// 创建顶点连接
	lines := make(map[string]*diLine)
	for _, v := range g.Vertexes {
		for _, adjV := range v.AdjacentVertexes {
			lines[MergeName(v.Out.Name, adjV.In.Name)] = &diLine{
				from: nodes[v.GetName()],
				to:   nodes[adjV.GetName()],
			}
		}
	}

	// 创建边
	edges := make(map[string]*cgraph.Edge)
	for _, e := range g.Edges {
		line, ok := lines[e.GetName()]
		if !ok {
			continue
		}

		edge, err := graph.CreateEdge(e.GetName(), line.from, line.to)
		if err != nil {
			return err
		}
		api := e.Api
		edge.SetLabel(fmt.Sprintf("%d/%d", api.Num, api.CallCount))
		edge.SetLabelFontColor("RED")
		edges[e.GetName()] = edge
	}

	// 保存到图片
	return gviz.RenderFilename(graph, graphviz.SVG, filename)
}
